package com.bwie.service;

import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bwie.domain.User;
import com.bwie.exdomain.EsUser;
import com.bwie.mapper.UserMapper;
import com.bwie.poi.StringUtils;
import com.bwie.utils.MobileMessageUtil;
import com.bwie.utils.R;
import com.bwie.utils.VerifyUtils;
import com.bwie.vo.LoginInfoVo;
import com.bwie.vo.PageInfoVo;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Author: lrz
 * @Date: 2024/10/21 09:19
 * @Description:
 **/
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserMapper userMapper;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Override
    public R login(LoginInfoVo loginInfoVo) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.lambda().eq(User::getUsername,loginInfoVo.getUserName());
        User user = userMapper.selectOne(userQueryWrapper);
        if(user==null){
            return R.ERROR(500,"用户名不存在");
        }
        if(!loginInfoVo.getUserPass().equals(user.getPassword())){
            return R.ERROR(500,"密码不正确");
        }
        String token = Jwts.builder().signWith(SignatureAlgorithm.HS256, "123456")
                .claim("userId", user.getId())
                .claim("userName", user.getUsername())
                .compact();
        String key = "token"+user.getId();
        stringRedisTemplate.opsForValue().set(key,token,20, TimeUnit.MINUTES);
        user.setToken(token);
        System.out.println("登录用户");
        System.out.println("登录用户");
        System.out.println("dasd");
        System.out.println("dsd");
        System.out.println("dsada");
        System.out.println("dsadjaio");
        System.out.println("dsajiodaji");
        System.out.println("dsahuidhi");
        System.out.println("dasjhuodau");
        System.out.println("dsabduia");
        System.out.println("dsahodia");
        System.out.println("dsjoiad");
        System.out.println("djsaidos");
        System.out.println("dashoda");
        System.out.println("djsaiosji");
        System.out.println("dsahoda");
        System.out.println("djsaio");
        System.out.println("dhisaoda");
        System.out.println("dhsioaid");
        System.out.println("dhsiaoj");
        System.out.println("djsaiohadji");
        System.out.println("dsjaiodaj");
        System.out.println("dsjaio");
        System.out.println("djisao");
        System.out.println("djsioai");
        System.out.println("dsajhioi");
        System.out.println("dsajido");
        System.out.println("dsao");
        System.out.println("dhisao");
        System.out.println("dsjiaoda");
        System.out.println("dshaodhu");
        System.out.println("dsajiodia");
        System.out.println("dshaiodi");
        System.out.println("djsaiod");
        System.out.println("dsjaidjoi");
        return R.OK(token);
    }

    @Override
    public R addUser(User user) {
        boolean b1 = VerifyUtils.containsNumber(user.getUsername());
        boolean b2 = VerifyUtils.containsLowerCaseLetter(user.getUsername());
        boolean b3 = VerifyUtils.containsUpperCaseLetter(user.getUsername());
        if(!b1 || !b2 || !b3){
            return R.ERROR(500,"用户名为大小写英文字母和数字");
        }
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.lambda().eq(User::getUsername,user.getUsername());
        User user1 = userMapper.selectOne(userQueryWrapper);
        if(user1!=null){
            return R.ERROR(500,"用户名已存在");
        }
        String key = "code"+user.getPhone();
        String s = stringRedisTemplate.opsForValue().get(key);
        if(!s.equals(user.getCode())){
            return R.ERROR(500,"验证码不正确");
        }
        userMapper.insert(user);
        return R.OK();
    }

    @Override
    public R getCode(String phone) {
        String code = RandomUtil.randomNumbers(4);
        if(phone.length()!=11){
            return R.ERROR(500,"手机号格式不正确");
        }
        Boolean aBoolean = MobileMessageUtil.sendMobileMessage(phone, code);
        if(!aBoolean){
            MobileMessageUtil.sendMobileMessage(phone, code);
        }
        String key = "code"+phone;
        stringRedisTemplate.opsForValue().set(key,code,5,TimeUnit.MINUTES);
        User user = new User();
        user.setCode(code);
        return R.OK();
    }

    @Override
    public R getUserListEs(PageInfoVo pageInfoVo) {

        //ES默认从0开始
        Integer pageNum = 0;
        if(pageInfoVo.getPageNum()>0){
            pageNum = pageInfoVo.getPageNum()-1;
        }
        PageRequest pageRequest = PageRequest.of(pageNum, pageInfoVo.getPageSize());



        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        if(!StringUtils.isEmpty(pageInfoVo.getKeyWord())){
            //用户名查询
            boolQueryBuilder.should(QueryBuilders.matchQuery("username",pageInfoVo.getKeyWord()));
            //手机号查询
            boolQueryBuilder.should(QueryBuilders.matchQuery("phone",pageInfoVo.getKeyWord()));
        }

        //增加高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("username").preTags("<font color='red'>").postTags("</font>");


        //时间区间查询
        if(!StringUtils.isEmpty(pageInfoVo.getBeginTime()) && !StringUtils.isEmpty(pageInfoVo.getEndTime())){
            boolQueryBuilder.must(
                    QueryBuilders.rangeQuery("time")
                            .format("yyyy-MM-dd HH:mm:ss")
                            .timeZone("GMT+8")
                            .gte(pageInfoVo.getBeginTime())
                            .lte(pageInfoVo.getEndTime())
            );
        }

        //根据用户ID倒序排序
        FieldSortBuilder id = new FieldSortBuilder("id").order(SortOrder.DESC);


        //分页
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withPageable(pageRequest)
                .withQuery(boolQueryBuilder)
                .withHighlightBuilder(highlightBuilder)
                .withSort(id);

        SearchHits<EsUser> search = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), EsUser.class);

        long total = search.getTotalHits();

        ArrayList<EsUser> esUserArrayList = new ArrayList<>();
        for (SearchHit<EsUser> searchHit : search.getSearchHits()) {
            EsUser esUser = searchHit.getContent();

            //读取高亮信息
            List<String> list = searchHit.getHighlightField("username");
            if(list!=null && list.size()>0){
                esUser.setUsername(list.get(0));
            }

            esUserArrayList.add(esUser);
        }

        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("total",total);
        hashMap.put("records",esUserArrayList);
        return R.OK(hashMap);
    }


}
